package com.mbc.common.manager;

import java.sql.SQLException;
import java.util.List;

import javax.persistence.FlushModeType;

import org.hibernate.CacheMode;

import com.mbc.common.data.RoleDataList;
import com.mbc.common.entities.LevelApplicationItem;
import com.mbc.common.entities.Role;
import com.mbc.common.exception.DataDuplicationException;
import com.mbc.common.exception.ForeignConflictException;
import com.mbc.common.param.CriteriaParams;
import com.mbc.common.utils.KeyGenerator;

public class RoleMgr extends AbstractMgr {
	
	public RoleMgr()
	{}
	
	public RoleMgr(String sessionId)
	{
		this.sessionId = sessionId;
	}
	
	public void createRole(Role role)throws Exception
	{
		openConnection();
		try {
			beginTransaction();
			
			role.setRoleID(KeyGenerator.generateKey(entityManager));
			
			if(role.getLevelAppItemList() != null)
			{
				for (LevelApplicationItem l_lvlAppItem : role.getLevelAppItemList()) {
					l_lvlAppItem.setRoleId(role.getRoleID());
					entityManager.persist(l_lvlAppItem);
				}
			}
			entityManager.persist(role);
			
			commitTransaction();
		} catch (Exception e) {
			rollbackTransaction();
			if(DataDuplicationException.isUniqueKyeError(e))
				throw new DataDuplicationException(e.getMessage());
			else
				throw e;
		}
		finally{
			closeConnection();
		}
	}
	
	public void updateRole(Role role)throws Exception
	{
		openConnection();
		try {
			beginTransaction();
			entityManager.merge(role);
//			entityManager.createNamedQuery("LevelApplicationItem.deleteByRoleId")
//			.setParameter("roleId", role.getRoleID())
//			.executeUpdate();
//			
//			for (LevelApplicationItem l_lvlAppItem : role.getLevelAppItemList()) {
//				l_lvlAppItem.setRoleId(role.getRoleID());
//				entityManager.persist(l_lvlAppItem);
//			}	
			commitTransaction();
		} catch (Exception e) {
			rollbackTransaction();
			throw e;
		}
		finally{
			closeConnection();
		}
	}
	
	public void deleteRole(long roleId)throws Exception{
		openConnection();
		try {
			beginTransaction();
			Role l_role = entityManager.find(Role.class, roleId);
			entityManager.createNamedQuery("LevelApplicationItem.deleteByRoleId")
			.setParameter("roleId", roleId)
			.executeUpdate();
			
			entityManager.remove(l_role);
			commitTransaction();
		} catch (Exception e) {
			rollbackTransaction();
			if(e.getCause().getCause().getCause() instanceof SQLException){
				if(ForeignConflictException.FOREIGN_CONFLICT_ERROR_CODE == ((SQLException)e.getCause().getCause().getCause()).getErrorCode())
					throw new ForeignConflictException(e);
				else
					throw e;
			}
			else
				throw e;
		}
		finally{
			closeConnection();
		}
	}
	
	public Role findRole(long roleId)throws Exception{
		openConnection();
		try {
			Role l_role = entityManager.find(Role.class, roleId);
			l_role.setLevelAppItemList(entityManager.createNamedQuery("LevelApplicationItem.findByRoleId", LevelApplicationItem.class)
					.setParameter("roleId", roleId)
					.getResultList());
			return l_role;
		} catch (Exception e) {
			throw e;
		}
		finally{
			closeConnection();
		}
	}
	
	public List<Role> findAll()throws Exception
	{
		openConnection();
		try {
			return entityManager.createNamedQuery("Role.findAll", Role.class).getResultList();
		} catch (Exception e) {
			throw e;
		}
		finally{
			closeConnection();
		}
	}
	
	public RoleDataList getRoleList(CriteriaParams cri)throws Exception{
		openConnection();
		try {
            String l_cri = " where r.roleName like '%" + cri.getKeyword() + "%' or r.description like '%" + cri.getKeyword() + "%'";
            String l_searchJPQL = "select r from Role r" + l_cri;
            List<Role> l_entityList = entityManager.createQuery(l_searchJPQL, Role.class)
                    .setFirstResult(cri.getIndex())
                    .setMaxResults(cri.getSize())
                    .getResultList();
            RoleDataList l_dataList = new RoleDataList();
            l_dataList.setEntityList(l_entityList);
            
            if(cri.getIndex() == 0){
            	String l_countQuery = "select count(r.roleID) from Role r" + l_cri;
            	l_dataList.setTotalRecord(entityManager.createQuery(l_countQuery, Long.class).getSingleResult());
            }
			return l_dataList;
		} catch (Exception e) {
			throw e;
		} finally{
			closeConnection();
		}
	}
	
	public List<LevelApplicationItem> getLevelAppItemByRoleId(long roleId)throws Exception{
		openConnection();
		try {
			return entityManager.createNamedQuery("LevelApplicationItem.findByRoleId", LevelApplicationItem.class).getResultList();
		} catch (Exception e) {
			throw e;
		} finally{
			closeConnection();
		}
	}
}
